//----------------------------------------------------------------------------------------
// @Project Includes
#include "includes.h"

//----------------------------------------------------------------------------------------
// @Local Macro Define in the module

//----------------------------------------------------------------------------------------
// @Local Type defines in the module

//----------------------------------------------------------------------------------------
// @Global Variables define in the module
stc_j1939_t g_stcJ1939 = {0};

//----------------------------------------------------------------------------------------
static void srv_j1939_generalResponse(uint8_t result);

// @Prototypes of functions in the module
static void srv_j1939_readRegParmAck(uint16_t addr, uint16_t reglen);
static void srv_j1939_readRealtimeAck(uint16_t addr, uint16_t reglen);

static void srv_j1939_ctlCmdAnaly(uint16_t cmd);
static void srv_j1939_writeRegParmAck(uint16_t addr, uint16_t reglen, uint8_t * pMsg);

//========================================================================================
/*
 * @Functions:   static void srv_j1939_generalResponse(uint8_t result)
 * @Description: 通用应答
 * @Parameters:  NONE
 * @Return:      NONE
 */
static void srv_j1939_generalResponse(uint8_t result)
{
		g_stcSrvCan.ungeneralResponse.Bit.u8result = result;
		g_stcSrvCan.ungeneralResponse.Bit.back1 = 0;
    if (g_stccan.vu8canTxMQPushLen < CAN_MAX_TX_SIZE)/*保护，防止溢出*/
    {
        /* Init Transmit frame*/
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].ExtId   = CAN_UPG_RESPOND_ID; 
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].IDE     = CAN_UPG_RESPOND_ID_IDE;  
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].RTR     = CAN_RTRQ_DATA;   
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].DLC     = CAN_TX_DLC;  
        memcpy(g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].Data ,&g_stcSrvCan.ungeneralResponse.Data[0],8);
        g_stccan.vu8canTxMQPushLen++;
    }
    if (g_stccan.vu8canTxMQPushLen >= CAN_MAX_TX_SIZE)
    {
        g_stccan.vu8canTxMQPushLen = 0;
    }			
		
}

/*
 * @Functions:   void srv_j1939_fwInfoCallback(void)
 * @Description: can回调
 * @Parameters:  NONE
 * @Return:      NONE
 */
void srv_j1939_fwInfoCallback(void)
{
    uint8_t writeBuf[UPDATE_TAG_SIZE] = {0};
    uint8_t readBuf[UPDATE_TAG_SIZE] = {0};
    uint16_t i = 0;			
		
		writeBuf[0] = 0x5A;
		writeBuf[1] = 0xA5;
		
		writeBuf[2] = 0x78;/*表明CAN升级标志*/
		writeBuf[3] = g_stcSrvCan.unfirmwareInfo.Bit.u16ver >> 0;
		writeBuf[4] = g_stcSrvCan.unfirmwareInfo.Bit.u16ver >> 8;
		writeBuf[5] = g_stcSrvCan.unfirmwareInfo.Bit.u32size >> 0;
		writeBuf[6] = g_stcSrvCan.unfirmwareInfo.Bit.u32size >> 8;		
		writeBuf[7] = g_stcSrvCan.unfirmwareInfo.Bit.u32size >> 16;
		writeBuf[8] = g_stcSrvCan.unfirmwareInfo.Bit.u32size >> 24;		
		writeBuf[9] = g_stcSrvCan.unfirmwareInfo.Bit.u16crc >> 0;/*根据协议特殊处理*/
		writeBuf[10] = g_stcSrvCan.unfirmwareInfo.Bit.u16crc >> 8;			
			
		drv_flash_write(writeBuf, OTA_CONFIG_ADDR, UPDATE_TAG_SIZE);
		drv_flash_read(readBuf, OTA_CONFIG_ADDR, UPDATE_TAG_SIZE);
		for (i = 0; i < UPDATE_TAG_SIZE; i++)
		{
				if (writeBuf[i] != readBuf[i])
				{
						MODBUS_DEBUG("Modbus:<< OTA write update data error!g_stcVar.m_stcUpgInfo[%d]=0x%0x tempBuf[%d]=0x%0x\r\n", i, writeBuf[i], i, readBuf[i]);
						memset((void *) writeBuf, 0x00, 11);
						drv_flash_write(writeBuf, OTA_CONFIG_ADDR, UPDATE_TAG_SIZE);
						srv_j1939_generalResponse(1);
						return ; 
				}
		}
		//srv_j1939_generalResponse(0);
		//gstcOtaUpdataInfo.u16fwCrc16 = 0; /* tuxin todo */

		MODBUS_DEBUG("Modbus:<< goto boot upgrade, restart and enter BOOT....\r\n ");
		drv_systick_delay_ms(30);
		NVIC_SystemReset();		
		
}

/*
 * @Functions:   void srv_j1939_fwDataCallback(void)
 * @Description: can回调
 * @Parameters:  NONE
 * @Return:      NONE
 */
void srv_j1939_fwDataCallback(void)
{
//		uint8_t i = 0;
//		uint8_t Temp[J1939_MAX_DATA_SIZE + 20] = {0};	
//	
//		if (g_stcSrvCan.unfirmwareData.Bit.u8packNumber == 0x00)/*升级包内容信息*/
//		{
//				g_stcJ1939.u32baseAddress = (((uint32_t)g_stcSrvCan.unfirmwareData.Data[1] << 24)| 
//																		((uint32_t)g_stcSrvCan.unfirmwareData.Data[2] << 16)| 
//																		((uint32_t)g_stcSrvCan.unfirmwareData.Data[3] << 8)| 
//																		((uint32_t)g_stcSrvCan.unfirmwareData.Data[4] << 0)  
//																		);	
//				g_stcJ1939.u16packLen = 		(((uint16_t)g_stcSrvCan.unfirmwareData.Data[5] << 8)| 
//																		((uint16_t)g_stcSrvCan.unfirmwareData.Data[6] << 0) 
//																		);
//        if ((g_stcJ1939.u16packLen % 7) != 0)
//				{
//						g_stcJ1939.u8packNum = g_stcJ1939.u16packLen / 7 + 1;
//				}	
//        else
//				{
//						g_stcJ1939.u8packNum = g_stcJ1939.u16packLen / 7;
//				}	
//        for (i = 0; i < g_stcJ1939.u8packNum; i++)
//				{
//						g_stcJ1939.bflag[i] = true;
//				}
//				memset(&g_stcJ1939.u8Temp,0x00,J1939_MAX_DATA_SIZE);	
//		}
//		else
//		{
//				if (g_stcSrvCan.unfirmwareData.Bit.u8packNumber == g_stcJ1939.u8packNum)/*最后一包*/
//				{
//					  g_stcJ1939.bflag[g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1] = false;
//						memcpy(&g_stcJ1939.u8Temp[(g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1)*7],&g_stcSrvCan.unfirmwareData.Data[1],(g_stcJ1939.u16packLen - (g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1)*7)); 					
//					  
//					  drv_flash_write(&g_stcJ1939.u8Temp[0], DEVICE_MAIN_APP_ADDR + g_stcJ1939.u32baseAddress, g_stcJ1939.u16packLen);
//            drv_flash_read(Temp, DEVICE_MAIN_APP_ADDR + g_stcJ1939.u32baseAddress, g_stcJ1939.u16packLen);
//            //gstcOtaUpdataInfo.u16fwCrc16 = srv_crc16_system(Temp,g_stcJ1939.u16packLen,gstcOtaUpdataInfo.u16fwCrc16);/* tuxin todo */
//					  for (i = 0; i < g_stcJ1939.u8packNum; i++)
//						{
//								if (g_stcJ1939.bflag[i] != false)
//								{
//										srv_j1939_generalResponse(1);
//									  return;
//								}
//						}
//						srv_j1939_generalResponse(0);
//						
//				}
//				else
//				{
//					  g_stcJ1939.bflag[g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1] = false;
//						memcpy(&g_stcJ1939.u8Temp[(g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1)*7],&g_stcSrvCan.unfirmwareData.Data[1],7); 
//				}
//		}
}

/*
 * @Functions:   bool_t srv_j1939_fwResultCallback(void)
 * @Description: can回调
 * @Parameters:  NONE
 * @Return:      NONE
 */
bool_t srv_j1939_fwResultCallback(void)
{
//    uint8_t writeBuf[UPDATE_TAG_SIZE] = {0};
//    //uint8_t readBuf[UPDATE_TAG_SIZE] = {0};
//		
//		#define MAGIC_ADDR_BASE   (0x8005000)
//		#define MAGIC_REVISION   ("CBMS-xxx-0328800387")
//		uint8_t cRevision_Magic[40] = {0};
//			
//		drv_flash_read(cRevision_Magic, MAGIC_ADDR_BASE, sizeof(MAGIC_REVISION));	

//		if (strcmp((char*)cRevision_Magic, MAGIC_REVISION) == 0)
//		{   
//				printf("magic check ok!\r\n");
//		}
//		else
//		{
//				srv_j1939_generalResponse(1);
//				printf("magic check error!\r\n");
//				return false;
//		}
//				
//		//if(gstcOtaUpdataInfo.u16fwCrc16  != gstcOtaUpdata.u16fwCrc16)
//		{
//				srv_j1939_generalResponse(1);
//				printf("crc check error! gstcOtaUpdataInfo.u16fwCrc16 = 0x%x gstcOtaUpdataInfo.u16fwCrc16 = 0x%x \r\n",
//			                           gstcOtaUpdataInfo.u16fwCrc16,gstcOtaUpdata.u16fwCrc16);
//				return false;
//		}
//		else
//		{
//				srv_j1939_generalResponse(0);
//			
//				memset((void *) writeBuf, 0x00, 11);
//				drv_flash_write(writeBuf, OTA_CONFIG_ADDR, UPDATE_TAG_SIZE);
//				printf("Modbus:<< The upgrade is complete, restart and enter BOOT....\r\n ");
//				return true;						
//		}
			return false;	
}

/**
 * @brief  read parm ack
 * @param  
 * @return 
 * @note   
 */
static void srv_j1939_readRegParmAck(uint16_t addr, uint16_t reglen)
{
    uint8_t u8TxBuf[1024];
	  uint8_t u8CanBuf[8];
    uint16_t u16count = 0;
//		uint16_t u16len = 0;
		uint16_t u16i = 0;
		uint16_t u16j = 0;
	  
		memset(&u8TxBuf,0x00,1024);
	
		srv_parm_readRegRefresh();
		for (u16i = 0; u16i < reglen; u16i++)           
		{
				u8TxBuf[u16count++] = g_u16RegParm[addr + u16i] >> 8;
				u8TxBuf[u16count++] = g_u16RegParm[addr + u16i] >> 0;
		}
		
		for (u16j = 0; u16j < reglen;) 
		{	
				u8CanBuf[0] = (u16j + addr) >> 8;
				u8CanBuf[1] = (u16j + addr) >> 0;
			  memcpy(&u8CanBuf[2],&u8TxBuf[u16j*2],6); 
				if (g_stccan.vu8canTxMQPushLen < CAN_MAX_TX_SIZE)/*保护，防止溢出*/
				{
						/* Init Transmit frame*/
						g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].ExtId   = CAN_READ_ACK_ID; 
						g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].IDE     = CAN_READ_ACK_ID_IDE;  
						g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].RTR     = CAN_RTRQ_DATA;   
						g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].DLC     = CAN_TX_DLC;  
						memcpy(g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].Data ,&u8CanBuf[0],8);
						g_stccan.vu8canTxMQPushLen++;
				}
				if (g_stccan.vu8canTxMQPushLen >= CAN_MAX_TX_SIZE)
				{
						g_stccan.vu8canTxMQPushLen = 0;
				}
				
				u16j += 3;
				memset(&u8CanBuf,0x00,8);
		}		

	
}

/**
 * @brief  read parm ack
 * @param  
 * @return 
 * @note   
 */
static void srv_j1939_readRealtimeAck(uint16_t addr, uint16_t reglen)
{
    uint8_t u8TxBuf[1024];
	  uint8_t u8CanBuf[8];
    uint16_t u16count = 0;
//		uint16_t u16len = 0;
		uint32_t u32temp = 0;
		uint16_t u16i = 0;
		uint16_t u16j = 0;
	  
		memset(&u8TxBuf,0x00,1024);
	
	  u8TxBuf[u16count++] = g_stcVar.u16voltMax >> 8;
    u8TxBuf[u16count++] = g_stcVar.u16voltMax;
	  u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = g_stcVar.u8voltMaxNum;	
	  u8TxBuf[u16count++] = g_stcVar.u16voltMin >> 8;
    u8TxBuf[u16count++] = g_stcVar.u16voltMin;
	  u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = g_stcVar.u8voltMinNum;	
		
    u8TxBuf[u16count++] = ((int16_t)g_stcVar.i8tempMax+TEMP_OFFSET) >> 8;
    u8TxBuf[u16count++] = ((int16_t)g_stcVar.i8tempMax+TEMP_OFFSET) >> 0;
	  u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = g_stcVar.u8maxTmprPos;			
    u8TxBuf[u16count++] = ((int16_t)g_stcVar.i8tempMin+TEMP_OFFSET) >> 8;
    u8TxBuf[u16count++] = ((int16_t)g_stcVar.i8tempMin+TEMP_OFFSET) >> 0;		
	  u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = g_stcVar.u8minTmprPos;	

		for (u16i = 0; u16i < BMS_MAX_CELLNUM; u16i++)
		{
				u8TxBuf[u16count++] = g_stcVar.u16cellVolt[u16i] >> 8;
				u8TxBuf[u16count++] = g_stcVar.u16cellVolt[u16i];
		}
	  u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = MAX_TMPR_NUM;	/*to define */
		for (u16i = 0; u16i < BMS_MAX_TEMPNUM; u16i++)
		{
			  u8TxBuf[u16count++] = 0;
        u8TxBuf[u16count++] = g_stcVar.i8cellTemp[u16i]+TEMP_OFFSET;
		}
		
		u32temp = 1000000 + (g_stcParm.stcConfig.u32designCap);
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0; 
		u32temp = 1000000 - (g_stcParm.stcConfig.u32designCap*2);
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16; 	
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0; 
		
    u8TxBuf[u16count++] = (g_stcVar.i32avgCurrent+1000000) >> 24;
    u8TxBuf[u16count++] = (g_stcVar.i32avgCurrent+1000000) >> 16;
    u8TxBuf[u16count++] = (g_stcVar.i32avgCurrent+1000000) >> 8;
    u8TxBuf[u16count++] = (g_stcVar.i32avgCurrent+1000000) >> 0;
    u8TxBuf[u16count++] = (g_stcVar.u32totalSumVolt) >> 24;
    u8TxBuf[u16count++] = (g_stcVar.u32totalSumVolt) >> 16;
    u8TxBuf[u16count++] = (g_stcVar.u32totalSumVolt) >> 8;
    u8TxBuf[u16count++] = (g_stcVar.u32totalSumVolt) >> 0;

		u32temp = (abs(g_stcVar.i32avgCurrent) *g_stcVar.u32totalSumVolt)/1000;
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16; 	
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0; 
		
		u8TxBuf[u16count++] = g_stcParm.stcConfig.u16cycleCount >> 8;
		u8TxBuf[u16count++] = g_stcParm.stcConfig.u16cycleCount;

    u8TxBuf[u16count++] = g_stcVar.u32balStat >> 8;
    u8TxBuf[u16count++] = g_stcVar.u32balStat;
    u8TxBuf[u16count++] = g_stcVar.u32balStat >> 24;
    u8TxBuf[u16count++] = g_stcVar.u32balStat >> 16;

    u8TxBuf[u16count++] = g_stcVar.unProtRank1.dword >> 8;
    u8TxBuf[u16count++] = g_stcVar.unProtRank1.dword;			
    u8TxBuf[u16count++] = g_stcVar.unProtRank1.dword >> 24;
    u8TxBuf[u16count++] = g_stcVar.unProtRank1.dword >> 16;

    u8TxBuf[u16count++] = g_stcVar.unProtRank2.dword >> 8;
    u8TxBuf[u16count++] = g_stcVar.unProtRank2.dword;			
    u8TxBuf[u16count++] = g_stcVar.unProtRank2.dword >> 24;
    u8TxBuf[u16count++] = g_stcVar.unProtRank2.dword >> 16;

    u8TxBuf[u16count++] = g_stcVar.unProtRank3.dword >> 8;
    u8TxBuf[u16count++] = g_stcVar.unProtRank3.dword;			
    u8TxBuf[u16count++] = g_stcVar.unProtRank3.dword >> 24;
    u8TxBuf[u16count++] = g_stcVar.unProtRank3.dword >> 16;

		memset(&u8TxBuf[u16count],0x00,8); /*to define */       
    u16count += 8; 
		
	  u8TxBuf[u16count++] = g_stcVar.u16voltDiff >> 8;
    u8TxBuf[u16count++] = g_stcVar.u16voltDiff;
		
	  u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = g_stcVar.i8mosTemp + TEMP_OFFSET;		
	  u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = g_stcVar.i8mosTemp + TEMP_OFFSET;		
	  u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = g_stcVar.i8ambTemp + TEMP_OFFSET;	
	  u8TxBuf[u16count++] = g_stcVar.u16canError >> 8;
    u8TxBuf[u16count++] = g_stcVar.u16canError >> 0;
		
    if(g_stcState.enstate == SST_CHG)
    {
        u8TxBuf[u16count++] =(g_stcSoc.u32chgRemainTime/60) >> 8;
        u8TxBuf[u16count++] = (g_stcSoc.u32chgRemainTime/60);     
    }
    else
    {
        u8TxBuf[u16count++] =(g_stcSoc.u32dsgRemainTime/60) >> 8;
        u8TxBuf[u16count++] = g_stcSoc.u32dsgRemainTime/60;       
    }

    if (false == srv_contactor_getState(CNT_CHG))
    {
        u8TxBuf[u16count++] = 0x00;
        u8TxBuf[u16count++] = 0x00;	        
    }
    else
    {
        u8TxBuf[u16count++] = 0x00;
        u8TxBuf[u16count++] = 0x01;       
    }		
    if (false == srv_contactor_getState(CNT_DSG))
    {
        u8TxBuf[u16count++] = 0x00;
        u8TxBuf[u16count++] = 0x00;	        
    }
    else
    {
        u8TxBuf[u16count++] = 0x00;
        u8TxBuf[u16count++] = 0x01;       
    }
    if (false == srv_contactor_getState(CNT_PCHG))
    {
        u8TxBuf[u16count++] = 0x00;
        u8TxBuf[u16count++] = 0x00;	        
    }
    else
    {
        u8TxBuf[u16count++] = 0x00;
        u8TxBuf[u16count++] = 0x01;       
    }
    if (false == srv_contactor_getState(CNT_PDSG))
    {
        u8TxBuf[u16count++] = 0x00;
        u8TxBuf[u16count++] = 0x00;	        
    }
    else
    {
        u8TxBuf[u16count++] = 0x00;
        u8TxBuf[u16count++] = 0x01;       
    }	

	  if((srv_signal_getChargeIn() == true)||(g_stcState.enstate == SST_CHG))	
		{
        g_stcVar.unmodleWorkState.bit.charge = 1;	
		}	
		else
		{
        g_stcVar.unmodleWorkState.bit.charge = 0;				
		}		
		if (abs(g_stcVar.i32avgCurrent) <= g_stcParm.stcConfig.u16curThr)
		{
				g_stcVar.unmodleWorkState.bit.bms = 0;
		}
    else if(g_stcState.enstate == SST_CHG)	
		{
        g_stcVar.unmodleWorkState.bit.bms = 1;	
		}	
		else
		{
        g_stcVar.unmodleWorkState.bit.bms = 2; 			
		}
		
//	  if(g_stcCommu.enState == SST_COMMU_CONNECT)	
//		{
//        g_stcVar.unmodleWorkState.bit.bt = 1;	
//		}	
//		else
//		{
//        g_stcVar.unmodleWorkState.bit.bt = 0;				
//		}			
    u8TxBuf[u16count++] = g_stcVar.unmodleWorkState.dword >> 8;
    u8TxBuf[u16count++] = g_stcVar.unmodleWorkState.dword;			
    u8TxBuf[u16count++] = g_stcVar.unmodleWorkState.dword >> 24;
    u8TxBuf[u16count++] = g_stcVar.unmodleWorkState.dword >> 16;		
	
    u8TxBuf[u16count++] = 0x00;
    u8TxBuf[u16count++] = 0x00;	
		
	  if (g_stcParm.stcConfig.u8capAutoLearn  == true)	
	  {
	      u8TxBuf[u16count++] = 0;	
	      u8TxBuf[u16count++] = 1; 
	  }
	  else
	  { 
	      u8TxBuf[u16count++] = 0;
	      u8TxBuf[u16count++] = 0;  
	  } 
	  u8TxBuf[u16count++] = 0;
	  u8TxBuf[u16count++] = 0; 
		
    u8TxBuf[u16count++] = (g_stcSoc.stcdata.u32displayValue/1000) >> 8;
    u8TxBuf[u16count++] = (g_stcSoc.stcdata.u32displayValue/1000) >> 0;
    u8TxBuf[u16count++] = (g_stcSoc.stcdata.u32trueValue/1000) >> 8;
    u8TxBuf[u16count++] = (g_stcSoc.stcdata.u32trueValue/1000) >> 0; 

    u8TxBuf[u16count++] = 0;
    u8TxBuf[u16count++] = g_stcParm.stcConfig.u8soh; 
		
		u32temp = g_stcParm.stcConfig.u32designCap;
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0; 
		u32temp = g_stcParm.stcConfig.u32fullChgCap;
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0; 
		
		u32temp = (((((uint64_t)g_stcParm.stcConfig.u32fullChgCap)/10)*(((uint64_t)g_stcSoc.stcdata.u32displayValue)/1000))/100);
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0;
		
		u32temp = (g_stcParm.stcConfig.u32fullChgCap)*(g_stcParm.stcConfig.u16cycleCount+1);
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0;		
		
		u32temp = ((g_stcParm.stcConfig.u32fullChgCap)*g_stcParm.stcConfig.u16cycleCount) +(((g_stcParm.stcConfig.u32fullChgCap/1000)*(g_stcSoc.stcdata.u32displayValue/1000)));
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0;	

		u32temp = g_stcParm.stcConfig.u32fullChgCap;
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0; 
		
	  u32temp = 0;
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0;

		u32temp = 0;
    u8TxBuf[u16count++] = u32temp >> 24;	
    u8TxBuf[u16count++] = u32temp >> 16;
    u8TxBuf[u16count++] = u32temp >> 8;	
    u8TxBuf[u16count++] = u32temp >> 0; 
		
		memset(&u8TxBuf[u16count],0x00,20);     
    u16count += 20; 
		
		memset(&u8TxBuf[u16count],0x00,102);     
    u16count += 102; 	
		
		for (u16j = 0; u16j < reglen;) 
		{	
				u8CanBuf[0] = (u16j + addr) >> 8;
				u8CanBuf[1] = (u16j + addr) >> 0;
			  memcpy(&u8CanBuf[2],&u8TxBuf[u16j*2],6); 
				if (g_stccan.vu8canTxMQPushLen < CAN_MAX_TX_SIZE)/*保护，防止溢出*/
				{
						/* Init Transmit frame*/
						g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].ExtId   = CAN_READ_ACK_ID; 
						g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].IDE     = CAN_READ_ACK_ID_IDE;  
						g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].RTR     = CAN_RTRQ_DATA;   
						g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].DLC     = CAN_TX_DLC;  
						memcpy(g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].Data ,&u8CanBuf[0],8);
						g_stccan.vu8canTxMQPushLen++;
				}
				if (g_stccan.vu8canTxMQPushLen >= CAN_MAX_TX_SIZE)
				{
						g_stccan.vu8canTxMQPushLen = 0;
				}
				
				u16j += 3;
				memset(&u8CanBuf,0x00,8);
		}		

	
}

/*
 * @Functions:   srv_j1939_readCallback(uint8_t * pMsg, uint8_t pMsgLen)
 * @Description: can回调
 * @Parameters:  NONE
 * @Return:      NONE
 */
void srv_j1939_readCallback(uint8_t * pMsg, uint8_t pMsgLen)
{
		uint16_t u16regStartAddr = 0;	
		uint16_t u16regLen = 0;	
	
		u16regStartAddr = (((uint16_t)pMsg[0] << 8) | ((uint16_t)pMsg[1]));
		u16regLen = (((uint16_t)pMsg[2] << 8) | ((uint16_t)pMsg[3]));
	
	  if ((u16regStartAddr >= J1939_BASICINFO_START_ADDR)&&(u16regStartAddr <= J1939_BASICINFO_END_ADDR))/*the basic info data */
		{
				srv_j1939_readRegParmAck(u16regStartAddr, u16regLen);
		}
		else if ((u16regStartAddr >= J1939_REALTIME_START_ADDR)&&(u16regStartAddr <= J1939_REALTIME_END_ADDR))/*the realtime info data */
		{
				srv_j1939_readRealtimeAck(u16regStartAddr, u16regLen);
		}
		else if ((u16regStartAddr >= J1939_CONFIGPARM_START_ADDR)&&(u16regStartAddr <= J1939_CONFIGPARM_END_ADDR))/*the sys parm info data */
		{
				srv_j1939_readRegParmAck(u16regStartAddr, u16regLen);
		}	
		else if ((u16regStartAddr >= J1939_SWPROTECTPARM_START_ADDR)&&(u16regStartAddr <= J1939_SWPROTECTPARM_END_ADDR))/*the sw protect parm info data */
		{
				srv_j1939_readRegParmAck(u16regStartAddr, u16regLen);	
		}	
		else if ((u16regStartAddr >= J1939_HWPROTECTPARM_START_ADDR)&&(u16regStartAddr <= J1939_HWPROTECTPARM_END_ADDR))/*the hw protect parm info data */
		{
				srv_j1939_readRegParmAck(u16regStartAddr, u16regLen);	
		}	
		else if ((u16regStartAddr >= J1939_CALPARM_START_ADDR)&&(u16regStartAddr <= J1939_CALPARM_END_ADDR))/*the hw protect parm info data */
		{
				srv_j1939_readRegParmAck(u16regStartAddr, u16regLen);		
		}	
		else
		{
		}		
	
}

/**
 * @brief  ctl cmd analy
 * @param  
 * @return 
 * @note   
 */
static void srv_j1939_ctlCmdAnaly(uint16_t cmd)
{
		switch (cmd)
		{
				case J1939_CMD_SHUTDOWN:
						srv_event_save(EVENT_TYPE_CMD , 0);	
						break;
				case J1939_CMD_DEFAULTFACTORY:
						srv_parm_defaultFactory(1);
						break;
				case J1939_CMD_RESET:
						NVIC_SystemReset();
						break;
				case J1939_CMD_PDSG:
            if (g_stcVar.bpdsgMosCtl== true)
            {
								g_stcVar.bpdsgMosCtl = false;
//								PDSG_RESET();
            }
            else
            {					
								g_stcVar.bpdsgMosCtl = true;
//								PDSG_SET();
            }						
						break;				
				case J1939_CMD_CHGSWITCH:
            if (g_stcVar.bchgMosCmdCtl== true)
            {
								g_stcVar.bchgMosCmdCtl = false;
            }
            else
            {					
								g_stcVar.bchgMosCmdCtl = true;
            }					
						break;
				case J1939_CMD_DSGSWITCH:
            if (g_stcVar.bdsgMosCmdCtl== true)
            {
								g_stcVar.bdsgMosCmdCtl = false;
            }
            else
            {					
								g_stcVar.bdsgMosCmdCtl = true;
            }						
						break;
				case J1939_CMD_DELEVENT:
						srv_event_delete();
						break;	
				case J1939_CMD_ENTERTEST:
						g_stcVar.bpvt = true;
						srv_parm_defaultFactory(0);
						break;	
				case J1939_CMD_EXITTEST:
						g_stcVar.bpvt = false;
						break;
				case J1939_CMD_SLEEP:
						g_stcVar.bcmdSleep = true;
						break;
				case J1939_CMD_POWERDOWN:
						g_stcVar.bcmdPowerDown = true;
						break;
				case J1939_CMD_CLEFAULT:
						break;
				case J1939_CMD_SOC:
						break;
				case J1939_CMD_HEAT:
//			      if (g_stcVar.bheatCmd== true)
//			      {
//								g_stcVar.bheatCmd = false;
//								HTR_RESET();
//								g_stcVar.bheatFlag = false;
//			      }
//			      else
//			      {					
//								g_stcVar.bheatCmd = true;
//								HTR_SET();
//								g_stcVar.bheatFlag = true;
//			      }					
						break;	
				case J1939_CMD_PCHG:
//            if (g_stcVar.bpchgMosCtl== true)
//            {
//								g_stcVar.bpchgMosCtl = false;
//								PCHG_RESET();
//            }
//            else
//            {					
//								g_stcVar.bpchgMosCtl = true;
//								PCHG_SET();
//            }						
						break;	
				case J1939_CMD_CLIMIT:
						break;					
				default:
						break;
		}
    			
}

/**
 * @brief  write parm ack
 * @param  
 * @return 
 * @note   
 */
static void srv_j1939_writeRegParmAck(uint16_t addr, uint16_t reglen, uint8_t * pMsg)
{
		uint16_t u16i = 0;
	  uint16_t u16ctlcmd = 0;

	  if (addr == REG_BASIC_RTC_TIME)
		{
				drv_rtc_setTime(&pMsg[2]);
		}
		else if (addr == COSM_CTL_ADDR)
		{
				u16ctlcmd = (((uint16_t)pMsg[2] << 8) | ((uint16_t)pMsg[3]));
			  srv_j1939_ctlCmdAnaly(u16ctlcmd);
		}
		else if (addr == COSM_BAL_ADDR)
		{
				g_stcVar.u32cmdBal = (((uint32_t)pMsg[4] << 24) | 
			                        ((uint32_t)pMsg[5] << 16) | 
															((uint32_t)pMsg[2] << 8) | 
															((uint32_t)pMsg[3] << 0)  
															);
		}

		else
		{
			for (u16i = 0; u16i < reglen; u16i++)
			{
					g_u16RegParm[addr + u16i] = (((uint16_t)pMsg[2+2*u16i] << 8) | ((uint16_t)pMsg[3+2*u16i]));
			}

			g_stcVar.bparmWriteFlag = true;
			g_stcVar.u16parmWriteWaitTime = PARM_WRITE_MAX_WAIT_TIME;			
		}
		
}

/*
 * @Functions:   srv_j1939_writeCallback(uint8_t * pMsg, uint8_t pMsgLen)
 * @Description: can回调
 * @Parameters:  NONE
 * @Return:      NONE
 */
void srv_j1939_writeCallback(uint8_t * pMsg, uint8_t pMsgLen)
{
		uint16_t u16regStartAddr = 0;	
		uint16_t u16regLen = 0;	
	
		u16regStartAddr = (((uint16_t)pMsg[0] << 8) | ((uint16_t)pMsg[1]));
		u16regLen = 3;//(((uint16_t)pMsg[2] << 8) | ((uint16_t)pMsg[3]));
	
	  if ((u16regStartAddr >= J1939_BASICINFO_START_ADDR)&&(u16regStartAddr <= J1939_BASICINFO_END_ADDR))/*the basic info data */
		{
				srv_j1939_writeRegParmAck(u16regStartAddr, u16regLen, pMsg);
		}
		else if ((u16regStartAddr >= J1939_CONFIGPARM_START_ADDR)&&(u16regStartAddr <= J1939_CONFIGPARM_END_ADDR))/*the sys parm info data */
		{
				srv_j1939_writeRegParmAck(u16regStartAddr, u16regLen, pMsg);		
		}	
		else if ((u16regStartAddr >= J1939_SWPROTECTPARM_START_ADDR)&&(u16regStartAddr <= J1939_SWPROTECTPARM_END_ADDR))/*the sw protect parm info data */
		{
				srv_j1939_writeRegParmAck(u16regStartAddr, u16regLen, pMsg);		
		}	
		else if ((u16regStartAddr >= J1939_HWPROTECTPARM_START_ADDR)&&(u16regStartAddr <= J1939_HWPROTECTPARM_END_ADDR))/*the hw protect parm info data */
		{
				srv_j1939_writeRegParmAck(u16regStartAddr, u16regLen, pMsg);	
		}	
		else if ((u16regStartAddr >= J1939_CALPARM_START_ADDR)&&(u16regStartAddr <= J1939_CALPARM_END_ADDR))/*the hw protect parm info data */
		{
				srv_j1939_writeRegParmAck(u16regStartAddr, u16regLen, pMsg);
		}
		else if (u16regStartAddr == J1939_CTL_ADDR)
		{
				srv_j1939_writeRegParmAck(u16regStartAddr, u16regLen, pMsg);		
		}
		else if (u16regStartAddr == J1939_BAL_ADDR)
		{
				srv_j1939_writeRegParmAck(u16regStartAddr, u16regLen, pMsg);	
		}
		else
		{
		}	
	
}

/*
 * @Functions:   void srv_j1939_generalWriteAck(void)
 * @Description: 通用写应答
 * @Parameters:  NONE
 * @Return:      NONE
 */
void srv_j1939_generalWriteAck(void)
{
	  uint8_t u8CanBuf[8];
	
		memset(&u8CanBuf,0xFF,8);
	
    if (g_stccan.vu8canTxMQPushLen < CAN_MAX_TX_SIZE)/*保护，防止溢出*/
    {
        /* Init Transmit frame*/
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].ExtId   = CAN_WRITE_ACK_ID; 
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].IDE     = CAN_WRITE_ACK_ID_IDE;  
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].RTR     = CAN_RTRQ_DATA;   
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].DLC     = CAN_TX_DLC;  
        memcpy(g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].Data ,&u8CanBuf[0],8);
        g_stccan.vu8canTxMQPushLen++;
    }
    if (g_stccan.vu8canTxMQPushLen >= CAN_MAX_TX_SIZE)
    {
        g_stccan.vu8canTxMQPushLen = 0;
    }			
		
}

/*
 * @Functions:   void srv_j1939_pcTask(void)
 * @Description: pc 上位机业务数据
 * @Parameters:  NONE for test
 * @Return:      NONE
 */
void srv_j1939_pcTask(void)
{
		//srv_j1939_readRegParmAck(0x0600, 0x002b);
}

// =======================================================================================
// End of file.
// =======================================================================================
